﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Xww.LCV.Model;
using Xww.Task;
using System.Text.RegularExpressions;


namespace Xww.LCV.Generator {
    // 计算连续长度的 LCV
    public class ConsecutiveSPLikeGenerator : BaseGenerator, ILCSGenerator {

        const int MaxLCVLength = 10;

        #region ILCSGenerator 成员

        public override LCSCollection FromStrings(IEnumerable<string> lines, MiningParam param) {
            List<LCS> rst = new List<LCS>();
            string TotalLines = string.Join(Environment.NewLine, lines.ToArray());

            var firstStepLCSs = this.FirstStep(lines, 0, param.Threshold);
            //不要长度为2的LCV
            HashSet<LCS> IterationStepLCS = firstStepLCSs;
            int IterationStep = 0;
            while (IterationStepLCS.Count > 1) {
                IterationStep += 1;
                int LCVLength = IterationStep + 2;
                if (LCVLength > MaxLCVLength) {
                    break;
                }

                HashSet<LCS> NotValidLCS = new HashSet<LCS>(LCS.InstanceForHash);

                var firsts = IterationStepLCS.GroupBy(o => o.SubFirstString).ToDictionary(o => o.Key, o => o);
                var lasts = IterationStepLCS.GroupBy(o => o.SubLastString).Where(o => firsts.ContainsKey(o.Key)).ToDictionary(o => o.Key, o => o);
                int total = 0;
                ProgressStatus count = new ProgressStatus(firsts.Count, string.Format("Grouping parant LCVs for merging bigger ones"));
                foreach (var item in lasts) {
                    StepChange(count);
                    total += item.Value.Count() * firsts[item.Key].Count();
                    count.ProgressOneStep();
                }

                ProgressStatus status = new ProgressStatus(total, string.Format("Interation step 【{0}】, generating LCV of length {1} from {2} LCVs", IterationStep, IterationStep + 2, IterationStepLCS.Count));

                HashSet<LCS> currentLCS = new HashSet<LCS>();
                foreach (var group in lasts) {
                    foreach (var the in group.Value) {
                        foreach (var other in firsts[group.Key]) {
                            StepChange(status);
                            status.ProgressOneStep();
                            // bigInterval 为新LCV的跨度间隔
                            int bigLastPosition = other.LastLocation + the.Locations[1] - other.FirstLocation;
                            if (bigLastPosition != LCVLength) // 限定必须为连续 LCV
                                continue;

                            LCS big = LCS.ImergeFirstLast(the, other);
                            if (currentLCS.Contains(big) || NotValidLCS.Contains(big)) {
                                continue;
                            }
                            big.Support = lines.Count(o => Regex.IsMatch(o, big.RegexString));
                            big.DeleteRegexString();
                            if (big.Support >= param.Threshold)
                                currentLCS.Add(big);
                            else
                                NotValidLCS.Add(big);
                        }
                    }
                }
                rst.AddRange(currentLCS);
                IterationStepLCS = currentLCS;
                currentLCS = null;
                NotValidLCS = null;
                firsts = null;
                lasts = null;
                GC.Collect();
            }
            return new LCSCollection(rst, "");
        }
        #endregion


    }
}